package com.wzh.glsc.product.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzh.common.constant.ProductConstant;
import com.wzh.common.to.MemberPriceTo;
import com.wzh.common.to.SkuReductionTo;
import com.wzh.common.to.SpuBoundsTo;
import com.wzh.common.to.es.SkuEsModel;
import com.wzh.common.utils.PageUtils;
import com.wzh.common.utils.Query;
import com.wzh.common.utils.R;
import com.wzh.glsc.product.dao.SpuInfoDao;
import com.wzh.glsc.product.entity.*;
import com.wzh.glsc.product.feign.CouponSpuBoundsFeignService;
import com.wzh.glsc.product.feign.ElasticSaveFeignService;
import com.wzh.glsc.product.feign.WareSkuWareFeignService;
import com.wzh.glsc.product.service.*;
import com.wzh.glsc.product.to.SkuHasStockTo;
import com.wzh.glsc.product.vo.BaseAttrs;
import com.wzh.glsc.product.vo.Images;
import com.wzh.glsc.product.vo.Skus;
import com.wzh.glsc.product.vo.SpuSaveVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Resource
    private SpuInfoDescService spuInfoDescService;
    @Resource
    private SpuImagesService spuImagesService;
    @Resource
    private AttrService attrService;
    @Resource
    private ProductAttrValueService productAttrValueService;
    @Resource
    private CouponSpuBoundsFeignService couponSpuBoundsFeignService;
    @Resource
    private SkuInfoService skuInfoService;
    @Resource
    private SkuImagesService skuImagesService;
    @Resource
    private SkuSaleAttrValueService skuSaleAttrValueService;
    @Resource
    private BrandService brandService;
    @Resource
    private CategoryService categoryService;
    @Resource
    private WareSkuWareFeignService wareSkuWareFeignService;
    @Resource
    private ElasticSaveFeignService elasticSaveFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveSpuInfo(SpuSaveVo spuSaveVo) {

        //spu信息：产品规格
        //        基本信息：宽、像素等;pms_spu_info
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtils.copyProperties(spuSaveVo, spuInfoEntity);
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());
        saveSpuInfoEntity(spuInfoEntity);

        //        描述图片：商品描述图片，可能是大字段。pms_spu_info_desc
        List<String> decript = spuSaveVo.getDecript();
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
        spuInfoDescEntity.setDecript(String.join(",", decript));
        spuInfoDescService.saveSpuInfoDesc(spuInfoDescEntity);

        //      图片集:商品的各图片，正面背面照等。pms_spu_images
        spuImagesService.saveSpuImages(spuInfoEntity.getId(), spuSaveVo.getImages());

        //      规格参数，是否快速展示、排序、颜色等。pms_product_attr_value
        List<BaseAttrs> baseAttrs = spuSaveVo.getBaseAttrs();
        List<ProductAttrValueEntity> productAttrValueEntities = baseAttrs.stream().map((tempObj) -> {
            ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
            AttrEntity attrEntity = attrService.getById(tempObj.getAttrId());
            productAttrValueEntity.setAttrId(attrEntity.getAttrId());
            productAttrValueEntity.setAttrName(attrEntity.getAttrName());
            productAttrValueEntity.setSpuId(spuInfoEntity.getId());
            productAttrValueEntity.setAttrValue(tempObj.getAttrValues());
            productAttrValueEntity.setQuickShow(tempObj.getShowDesc());
            return productAttrValueEntity;
        }).collect(Collectors.toList());
        productAttrValueService.saveProductAttrValue(productAttrValueEntities);

        //      商品购买后的积分信息。glsc-sms库下的sms_spu_bounds
        SpuBoundsTo spuBoundsTo = new SpuBoundsTo();
        BeanUtils.copyProperties(spuSaveVo.getBounds(), spuBoundsTo);
        spuBoundsTo.setSupId(spuInfoEntity.getId());
        R r = couponSpuBoundsFeignService.saveSpuBoundsBySpuBoundsTo(spuBoundsTo);
        if (r.getCode() != 0) {
            log.error("远程保存spu积分信息失败");
        }
        //sku信息：销售属性
        List<Skus> skusList = spuSaveVo.getSkus();
        skusList.forEach(item -> {
            String defaultImg = "";
            for (Images tempImgObj : item.getImages()) {
                if (tempImgObj.getDefaultImg() == 1) {
                    defaultImg = tempImgObj.getImgUrl();
                }
            }
            ;
            SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
            BeanUtils.copyProperties(item, skuInfoEntity);
            skuInfoEntity.setSpuId(spuInfoEntity.getId());
            skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
            skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
            skuInfoEntity.setSkuDefaultImg(defaultImg);
            skuInfoEntity.setSaleCount(0L);

            //      基本信息：所属分类价格等。pms_sku_info
            skuInfoService.saveSkuInfo(skuInfoEntity);

            //      图片信息：pms_sku_images
            List<SkuImagesEntity> skuImagesEntityCollect = item.getImages().stream().map((imgaesItem) -> {
                SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                BeanUtils.copyProperties(imgaesItem, skuImagesEntity);
                skuImagesEntity.setSkuId(skuInfoEntity.getSkuId());
                return skuImagesEntity;
            }).filter(item2 -> StringUtils.isNotEmpty(item2.getImgUrl())).collect(Collectors.toList());
            skuImagesService.saveSkuImagesBySkuImagesList(skuImagesEntityCollect);

            //      销售属性：pms_sku_sale_attr_value
            List<SkuSaleAttrValueEntity> skuSaleAttrValueEntityList = item.getAttr().stream().map(attrVoItem -> {
                SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                BeanUtils.copyProperties(attrVoItem, skuSaleAttrValueEntity);
                skuSaleAttrValueEntity.setSkuId(skuInfoEntity.getSkuId());
                skuSaleAttrValueEntity.setAttrId(attrVoItem.getAttrId());
                return skuSaleAttrValueEntity;
            }).collect(Collectors.toList());
            skuSaleAttrValueService.saveSkuSaleAttrValue(skuSaleAttrValueEntityList);

            //      折扣、满减、会员价等。glsc-sms库下的
            //                 sms_sku_ladder:折扣、
            //                 sms_sku_full_reduction：满减、
            //                 sms_member_price：会员价
            SkuReductionTo skuReductionTo = new SkuReductionTo();
            skuReductionTo.setSkuId(skuInfoEntity.getSkuId());
            BeanUtils.copyProperties(item, skuReductionTo);
            List<MemberPriceTo> memberPriceToList = item.getMemberPrice().stream().map(memberPrice -> {
                MemberPriceTo memberPriceTo = new MemberPriceTo();
                BeanUtils.copyProperties(memberPrice, memberPriceTo);
                return memberPriceTo;

            }).collect(Collectors.toList());
            skuReductionTo.setMemberPriceTos(memberPriceToList);
            if (skuReductionTo.getFullCount() > 0 || skuReductionTo.getFullPrice().compareTo(new BigDecimal("0")) == 1) {
                R r2 = couponSpuBoundsFeignService.saveSkuReduction(skuReductionTo);
                if (r2.getCode() != 0) {
                    log.error("远程保存sku折扣信息失败");
                }
            }
        });
    }

    @Override
    public PageUtils queryPageByParams(Map<String, Object> params) {
        String key = (String) params.get("key");
        QueryWrapper<SpuInfoEntity> spuInfoEntityQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty((String) params.get("brandId")) && !"0".equals((String) params.get("brandId"))) {
            spuInfoEntityQueryWrapper.eq("brand_id", (String) params.get("brandId"));
        }
        if (StringUtils.isNotEmpty((String) params.get("catelogId")) && !"0".equals((String) params.get("catelogId"))) {
            spuInfoEntityQueryWrapper.eq("catalog_id", (String) params.get("catelogId"));
        }
        if (StringUtils.isNotEmpty((String) params.get("status"))) {
            spuInfoEntityQueryWrapper.eq("publish_status", (String) params.get("status"));
        }
        if (StringUtils.isNotEmpty(key)) {
            spuInfoEntityQueryWrapper.and((obj) -> {
                obj.eq("spu_id", key).or().like("spu_name", key)
                        .or().like("spu_description", key)
                        .or().like("create_time", key)
                        .or().like("update_time", key);
            });
        }
        IPage<SpuInfoEntity> spuInfoEntityIPage = this.page(new Query<SpuInfoEntity>().getPage(params), spuInfoEntityQueryWrapper);
        return new PageUtils(spuInfoEntityIPage);
    }

    @Override
    public void productUp(Long spuId) {
        //上架的商品集合
        List<SkuEsModel> skuEsModelList = new ArrayList<>();

        //查出商品sku信息、品牌名,并封装成 SkuEsModel
        List<SkuInfoEntity> skuInfoList = skuInfoService.getSkuBySpuId(spuId);
        List<Long> skuIdList = skuInfoList.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
        Set<Long> skuIdSet = new HashSet<>();
        //商品规格参数
        List<ProductAttrValueEntity> productAttrValueEntities = productAttrValueService.getProductAttrValueEntityBySpuId(spuId);
        List<Long> attrIdList = productAttrValueEntities.stream().map(productAttrValueEntity -> {
            return productAttrValueEntity.getAttrId();
        }).collect(Collectors.toList());
        // 查出可以被检索的attrId
        List<Long> filterAttrIdList = attrService.getSearchAttrIdByAttrs(attrIdList);
        Set<Long> filterAttrIdSet = new HashSet<>(filterAttrIdList);
        List<SkuEsModel.Attrs> attrsList = productAttrValueEntities.stream()
                .filter(productAttrValueEntity -> filterAttrIdSet.contains(productAttrValueEntity.getAttrId()))
                .map((productAttrValueEntity) -> {
                    SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
                    BeanUtils.copyProperties(productAttrValueEntity, attrs);
                    return attrs;
                }).collect(Collectors.toList());

        List<SkuHasStockTo> skuHasStockTos = null;
        try {
            //查出是否有库存
            //Boolean hasStock;
            R r = wareSkuWareFeignService.hasstock(skuIdList);
            TypeReference<List<SkuHasStockTo>> typeReference = new TypeReference<List<SkuHasStockTo>>() {
            };
            skuHasStockTos = r.getData(typeReference);
        } catch (Exception e) {
            log.error("库存系统异常{}", e);
        }

        //将list转成map
        Map<Long, Boolean> stockCollect = skuHasStockTos == null ? null : skuHasStockTos.stream().collect(
                Collectors.toMap(SkuHasStockTo::getSkuId,
                        SkuHasStockTo::getHasStock,(s,s2)->s2));

        //封装上架的商品对象
        skuEsModelList = skuInfoList.stream().map(skuInfoEntity -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtils.copyProperties(skuInfoEntity, skuEsModel);
            skuEsModel.setSkuImg(skuInfoEntity.getSkuDefaultImg());
            skuEsModel.setSkuPrice(skuInfoEntity.getPrice());
            skuIdSet.add(skuInfoEntity.getSkuId());
            //品牌信息
            BrandEntity brandEntity = brandService.getById(skuInfoEntity.getBrandId());
            skuEsModel.setBrandImg(brandEntity.getName());
            skuEsModel.setBrandName(brandEntity.getName());
            //添加分类信息
            CategoryEntity categoryEntity = categoryService.getById(skuInfoList.get(0).getCatalogId());
            skuEsModel.setCatalogName(categoryEntity.getName());
            //TODO 热度可以细分，当时先为0
            skuEsModel.setHotScore(0L);
            //添加规格参数,attrsList是根据spuid查出的的规格参数，那么spu对应sku是一样的属性
            skuEsModel.setAttrs(attrsList);
            skuEsModel.setHasStock(stockCollect == null ? true
                            : (stockCollect.get(skuInfoEntity.getSkuId()) == null ? false
                            : stockCollect.get(skuInfoEntity.getSkuId())
                    )
            );
//            skuHasStockTos.
            return skuEsModel;
        }).collect(Collectors.toList());

        //将数据保存到es中
        R r = elasticSaveFeignService.productStatusUp(skuEsModelList);
        if (r.getCode() == 0) {
            SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
            spuInfoEntity.setId(spuId);
            spuInfoEntity.setUpdateTime(new Date());
            spuInfoEntity.setPublishStatus(ProductConstant.StatusEnum.SPU_UP.getCode());
            baseMapper.updateById(spuInfoEntity);
        } else {
            //TODO feign调用失败怎么办,接口幂等性;
        }
    }


    private void saveSpuInfoEntity(SpuInfoEntity spuInfoEntity) {
        baseMapper.insert(spuInfoEntity);
    }


}